package list;

public class NumLinkedList implements MyLinkedList{

    private NumLinkedListNode numLinkedListNode;
    private Integer size = 0;

    public NumLinkedList() {
    }

    @Override
    public int get(int index) {
        NumLinkedListNode indexNode = getNode(index);
        return indexNode == null ? -1 : indexNode.val;
    }

    public NumLinkedListNode getNode(int index) {
        if (index > size) {
            return null;
        }
        NumLinkedListNode re = numLinkedListNode;
        for (int i = 0; i <= index; i++) {
            if (i == index) {
                return re;
            }
            re = re.next;
        }
        return null;
    }

    @Override
    public void addAtHead(int val) {
        if (numLinkedListNode == null) {
            numLinkedListNode = new NumLinkedListNode(val, null);
        } else {
            numLinkedListNode = new NumLinkedListNode(val, numLinkedListNode);
        }
        size++;
    }

    @Override
    public void addAtTail(int val) {
        if (numLinkedListNode == null) {
            addAtHead(val);
            return;
        }
        NumLinkedListNode tail = numLinkedListNode;
        while (tail.next != null) {
            tail = tail.next;
        }
        tail.next = new NumLinkedListNode(val, null);
        size++;
    }

    @Override
    public void addAtIndex(int index, int val) {
        if (index > size || index < 0) {
            return;
        }
        if (index == 0) {
            addAtHead(val);
            return;
        }
        if (index == size) {
            addAtTail(val);
            return;
        }
        NumLinkedListNode indexNode = new NumLinkedListNode(val, null);
        NumLinkedListNode beforeNode = getNode(index - 1);
        indexNode.next = beforeNode.next;
        beforeNode.next = indexNode;
        size++;
    }

    @Override
    public void deleteAtIndex(int index) {
        if (index >= size || index < 0) {
            return;
        }
        if (index == 0) {
            numLinkedListNode = getNode(index + 1);
            size--;
            return;
        }
        getNode(index - 1).next = getNode(index).next;
        size--;
    }

    @Override
    public String toString() {
        return "NumLinkedList{" +
                "numLinkedListNode=" + numLinkedListNode;
    }

    private static class NumLinkedListNode {
        Integer val;
        NumLinkedListNode next;

        public NumLinkedListNode(Integer val, NumLinkedListNode next) {
            this.val = val;
            this.next = next;
        }

        @Override
        public String toString() {
            return "NumLinkedListNode{" +
                    "val=" + val +
                    ", next=" + next +
                    '}';
        }
    }

    public static void main(String[] args) {
        NumLinkedList numLinkedList = new NumLinkedList();
        numLinkedList.addAtHead(1);
        numLinkedList.addAtTail(3);
        System.out.println(numLinkedList);
        numLinkedList.addAtIndex(1, 2);
        System.out.println(numLinkedList);
        System.out.println(numLinkedList.get(1));
        numLinkedList.deleteAtIndex(1);
        System.out.println(numLinkedList);
        System.out.println(numLinkedList.get(1));
    }
}
